home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
admin
/
linuxcon.000
/
linuxcon
/
linuxconf-1.6
/
xconf
/
component.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-12
|
8KB
|
341 lines
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include "../misc/misc.h"
#include "xconf.h"
#include "components.h"
PUBLIC COMPONENT::COMPONENT(
const char *manuf_id,
const char *model_id,
XCONFIG *_xconfig,
NOTICE *_notice,
ACTION *_action)
: PAIRES (manuf_id,model_id)
{
xconfig = _xconfig;
notice = _notice;
action = _action;
}
PUBLIC COMPONENTS::COMPONENTS()
{
max_component = 0;
nb_component = 0;
tb_component = NULL;
max_xconfig = 0;
nb_xconfig = 0;
tb_xconfig = NULL;
max_notice = 0;
nb_notice = 0;
tb_notice = NULL;
}
PUBLIC VIRTUAL COMPONENTS::~COMPONENTS()
{
for (int i=0; i<nb_component; i++) delete tb_component[i];
free (tb_component);
for (i=0; i<nb_xconfig; i++) delete tb_xconfig[i];
free (tb_xconfig);
for (i=0; i<nb_notice; i++) delete tb_notice[i];
free (tb_notice);
}
/*
Add a new component to the list
*/
PUBLIC void COMPONENTS::add (COMPONENT *comp)
{
if (nb_component == max_component){
max_component += 50;
tb_component = (COMPONENT**)realloc(tb_component
,sizeof(XCONFIG*)*max_component);
}
tb_component[nb_component++] = comp;
}
/*
Add a new partial Xconfig to the list
*/
PUBLIC void COMPONENTS::add (XCONFIG *xconf)
{
if (nb_xconfig == max_xconfig){
max_xconfig += 10;
tb_xconfig = (XCONFIG**)realloc(tb_xconfig
,sizeof(XCONFIG*)*max_xconfig);
}
tb_xconfig[nb_xconfig++] = xconf;
}
/*
Add a new notice to the list
*/
PUBLIC void COMPONENTS::add (NOTICE *notice)
{
if (nb_notice == max_notice){
max_notice += 10;
tb_notice = (NOTICE**)realloc(tb_notice
,sizeof(NOTICE*)*max_notice);
}
tb_notice[nb_notice++] = notice;
}
/*
Read and parse a xconf file
*/
PUBLIC int COMPONENTS::read (const char *fname)
{
int ret = -1;
FILE *fin = xconf_fopen (fname,"r");
if (fin != NULL){
char buf[300];
ret = 0;
XCONFIG *xconfig = NULL;
NOTICE *notice = NULL;
ACTION *action = NULL;
char manuf[100];
manuf[0] = '\0';
char doing_xconfig = 0; // Parsing between @ paires ?
char doing_notice = 0; // Parsing between ! paires ?
char doing_action = 0; // Parsing between $ paires ?
int noline = 0;
while (fgets(buf,sizeof(buf)-1,fin)!= NULL){
noline++;
str_strip (buf,buf);
/* #Specification: data files / *.xconf
file *.xconf are lists of hardware components
(either screen or adaptor). The format is simple
although not so visual.
-manufacturer ID
@
parts of an Xconfig file useful for the
next component model following this section
@
model ID
Another model sharing the same configuration
@
A different Xconfig setup
@
!
A notice applying to following component
The notice hold true until a new notice
is entered.
!
$
A script to execute to make the configuration
effective. The script will be valid for
all following model
$
another model ID
-another manufacturer
Note also that the configurator merge several *.xconf files.
For example, I expect that a *.xconf file will be bundle
with each specific X server available (Mach32 SVGA etc...)
Here is a small example
-ATI
@
ACCEL
Clocks 100.0 126.0 92.4 36.0 50.35 56.64 0 44.90
135.0 32.0 110.0 80.0 39.91 49.90 75.0 65.0
Option "sw_cursor"
Modes "1024x768"
@
$
ln -sf /usr/X11R6/bin/XF86_Mach32 /usr/X11R6/bin/X
$
vlb Mach32
!
Please note that the busmouse on the Mach8 and Mach32
has to be configurer on IRQ 5.
!
Mach32 ultra
!
!
-Genoa
.
.
Line beginning with a # is a comment. Empty lines are
allowed.
*/
/* #Specification: data files / *.xconf / order
There is no need to put all products of a manufacturer
in the same section. Xconfigs may appear anywhere
and are shared between manufacturer. The following is
valid.
@
long Xconfig configuration
.
@
-manuf1
model1
model2
-manuf2
model4
@
other long configuration
@
-manuf1
model3
*/
char *pt = buf;
while (isspace (*pt)) pt++;
if (pt[0] != '#' && pt[0] != '\0'){
if (pt[0] == '-'){
pt++;
while (isspace(*pt)) pt++;
strcpy (manuf,pt);
}else if (pt[0] == '@'){
if (doing_xconfig){
doing_xconfig = 0;
}else{
doing_xconfig = 1;
xconfig = new XCONFIG;
add (xconfig);
}
}else if (pt[0] == '!'){
if (doing_notice){
doing_notice = 0;
}else if (pt[1] == '!'){
/* #Specification: data files / *.xconf / null notice
A line with !! indicate a null notice until
a new one is seen.
A line with $$ indicate a null action
*/
notice = NULL;
}else{
doing_notice = 1;
notice = new NOTICE;
add (notice);
}
}else if (pt[0] == '$'){
if (doing_action){
doing_action = 0;
}else if (pt[1] == '$'){
action = NULL;
}else{
doing_action = 1;
action = new ACTION;
add (action);
}
}else if (doing_xconfig){
xconfig->parse (buf,fname,noline);
}else if (doing_notice){
notice->add (pt);
}else if (doing_action){
action->add (pt);
}else{
// This is a model ID
add (new COMPONENT (manuf,pt,xconfig,notice,action));
}
}
}
fclose (fin);
}
return ret;
}
static int cmp (const void **pp1, const char **pp2)
{
COMPONENT *p1 = (COMPONENT *)(*pp1);
COMPONENT *p2 = (COMPONENT *)(*pp2);
int ret = strcmp(p1->keyw,p2->keyw);
if (ret == 0) ret = strcmp(p1->arg,p2->arg);
return ret;
}
/*
Sort all COMPONENT by manuf_id and model_id.
*/
PUBLIC void COMPONENTS::sort ()
{
qsort (tb_component,nb_component,sizeof(COMPONENT*),cmp);
}
/*
Print all COMPONENTS with the same format as input, mostly to debug
*/
PUBLIC void COMPONENTS::print (FILE *fout)
{
XCONFIG *xconfig=NULL;
NOTICE *notice=NULL;
ACTION *action=NULL;
char manuf[100];
manuf[0] = '\0';
for (int i=0; i<nb_component; i++){
COMPONENT *comp = tb_component[i];
if (strcmp(comp->keyw,manuf)!=0){
strcpy (manuf,comp->keyw);
fprintf (fout,"-%s\n",manuf);
}
if (comp->xconfig != xconfig){
xconfig = comp->xconfig;
fprintf (fout,"\t@\n");
xconfig->print (fout,2);
fprintf (fout,"\t@\n");
}
if (comp->notice != notice){
notice = comp->notice;
fprintf (fout,"\t!\n");
notice->print (fout,2);
fprintf (fout,"\t!\n");
}
if (comp->action != action){
action = comp->action;
fprintf (fout,"\t$\n");
action->print (fout,2);
fprintf (fout,"\t$\n");
}
fprintf (fout,"\t%s\n",comp->arg);
}
}
/*
Encode de component ids in a string table so it fit the dialog system.
tb[optnum*2] = manuf_id;
tb[optnum*2+1] = model_id;
Return the number of components placed in tbopt2, not the number of
strings.
*/
PUBLIC int COMPONENTS::setmenu (
char *tbopt2[])
{
int nb = 0;
char *manuf = NULL;
for (int i=0; i<nb_component; i++){
COMPONENT *comp = tb_component[i];
if (manuf == NULL || strcmp(comp->keyw,manuf)!=0){
manuf = comp->keyw;
tbopt2[nb++] = manuf;
}else{
tbopt2[nb++] = " ";
}
tbopt2[nb++] = comp->arg;
}
tbopt2[nb] = NULL;
return nb_component;
}
PUBLIC COMPONENT *COMPONENTS::item(int no)
{
COMPONENT *ret = NULL;
if (no >= 0 && no < nb_component) ret = tb_component[no];
return ret;
}
#ifdef TEST
int main (int argc, char *argv[])
{
COMPONENTS comp;
comp.read ("adaptors.xconf");
comp.sort ();
comp.print (stdout);
return 0;
}
#endif